#include "pch.h"
#include "CConfigFileManager.h"

CConfigFileManager::CConfigFileManager():m_ConfigFilePath(GetFileConfigPath())
{
	m_bLoad = false;
	bool ret = ParseConfigFile();
}

CConfigFileManager::~CConfigFileManager()
{
}

bool CConfigFileManager::ParseConfigFile()
{
	if (m_bLoad == true)
	{
		return true;
	}
	if (INVALID_FILE_ATTRIBUTES == ::GetFileAttributes(m_ConfigFilePath.c_str()))
	{
		AfxMessageBox(L"failed open config file");
		return false;
	}
	std::string path = Unicode2Ansi(m_ConfigFilePath);
	TiXmlDocument config(path.c_str());
	if (!config.LoadFile())
	{
		return false;
	}
	TiXmlNode* RootNode = config.FirstChild("configuration");
	if (RootNode == nullptr)
	{
		return false;
	}
	ParseIOSetting(RootNode);
	ParseAxisSetting(RootNode);
	m_bLoad = true;
	return true;
}

std::wstring CConfigFileManager::GetFileConfigPath()
{
	TCHAR  moduleFileName[MAX_PATH];
	::GetModuleFileName(NULL, moduleFileName, MAX_PATH);
	std::wstring filePath(moduleFileName);
	filePath.append(L".config");
	return filePath;
}

void CConfigFileManager::ParseIOSetting(TiXmlNode * node)
{
	TiXmlNode* IOnode=node->FirstChild("IOSetting");
	if (IOnode == nullptr)
	{
		return;
	}
	TiXmlElement* element = IOnode->ToElement();
	if (element != nullptr)
	{
		TiXmlElement* pElement;
		for (pElement = element->FirstChildElement(); pElement;pElement=pElement->NextSiblingElement())
		{
			IO_MODULE IO;
			pElement->QueryIntAttribute("port", &IO.m_nPort);
			pElement->QueryIntAttribute("type", &IO.m_nType);
			std::string description;
			description=pElement->Attribute("description");
			std::wstring wsDes = Utf8ToUnicode(description);
			IO.m_cstrDescription = wsDes.c_str();

			if (IO.m_nType == 0)
			{
				m_vIOInputSetting.push_back(IO);
			}
			else if (IO.m_nType == 1)
			{
				m_vIOOutputSetting.push_back(IO);
			}
		}
	}
	return;
}

void CConfigFileManager::ParseAxisSetting(TiXmlNode * node)
{
	TiXmlNode* Axisnode = node->FirstChild("AxisSetting");
	if (Axisnode == nullptr)
	{
		return;
	}
	TiXmlElement* element = Axisnode->ToElement();
	if (element != nullptr)
	{
		TiXmlElement* pElement;
		for (pElement = element->FirstChildElement(); pElement; pElement = pElement->NextSiblingElement())
		{
			AXIS_SETTING axis_Setting;
			pElement->QueryIntAttribute("nId", &axis_Setting.m_nAxisId);
			pElement->QueryIntAttribute("SpeedHome", &axis_Setting.m_nSpeedHome);
			pElement->QueryIntAttribute("SpeedMove", &axis_Setting.m_nSpeedMove);
			pElement->QueryIntAttribute("Direction", &axis_Setting.m_nDirection);
			pElement->QueryDoubleAttribute("SpeedTime", &axis_Setting.m_nSpeedAcc);
			pElement->QueryIntAttribute("StartSpeed", &axis_Setting.m_nStartSpeed);

			std::string name;
			name = pElement->Attribute("name");
			std::wstring wname = Utf8ToUnicode(name);
			axis_Setting.m_wstrAxisName = wname.c_str(); 
			std::string proportion;
			proportion = pElement->Attribute("proportion");
			std::wstring wproportion = Utf8ToUnicode(proportion);
			axis_Setting.m_wstrProportion = wproportion.c_str();
			m_dictAxisSetting[axis_Setting.m_nAxisId] = axis_Setting;
		}
	}
	return;
}

void CConfigFileManager::ResetData()
{
	m_bLoad = false;
	m_vIOInputSetting.clear();
	m_vIOOutputSetting.clear();
	m_dictAxisSetting.clear();
}

void CConfigFileManager::ReloadConfigFile()
{
	ResetData();
	ParseConfigFile();
}

bool CConfigFileManager::UpdateAxisSetting(std::wstring id, AXIS_SETTING axissetting)
{
	std::string path = Unicode2Ansi(m_ConfigFilePath);
	TiXmlDocument config(path.c_str());
	if (!config.LoadFile())
	{
		return false;
	}
	TiXmlNode* RootNode = config.FirstChild("configuration");
	if (RootNode == nullptr)
	{
		return false;
	}
	TiXmlNode* setNode = RootNode->FirstChild("AxisSetting");
	if (setNode == nullptr)
	{
		return false;
	}
	TiXmlElement* element = setNode->ToElement();
	if (element == nullptr)
	{
		return false;
	}
	for (TiXmlElement* pElement = element->FirstChildElement(); pElement; pElement = pElement->NextSiblingElement())
	{
		TiXmlElement* nElement = pElement->ToElement();
		std::string strid;
		strid = pElement->Attribute("nId");
		std::wstring wstrId = AnsiToUnicode(strid);
		if (wstrId == id)
		{
			CString cstr;
			cstr.Format(L"%d", axissetting.m_nSpeedHome);
			std::string stra = Unicode2Ansi(cstr.GetBuffer());
			nElement->SetAttribute("SpeedHome", stra.c_str());
			
			cstr.Format(L"%d", axissetting.m_nSpeedMove);
			stra = Unicode2Ansi(cstr.GetBuffer());
			nElement->SetAttribute("SpeedMove", stra.c_str());

			cstr.Format(L"%d", axissetting.m_nDirection);
			stra = Unicode2Ansi(cstr.GetBuffer());
			nElement->SetAttribute("Direction", stra.c_str());

			cstr.Format(L"%.2f", axissetting.m_nSpeedAcc);
			stra = Unicode2Ansi(cstr.GetBuffer());
			nElement->SetAttribute("SpeedTime", stra.c_str());

			cstr.Format(L"%d", axissetting.m_nStartSpeed);
			stra = Unicode2Ansi(cstr.GetBuffer());
			nElement->SetAttribute("StartSpeed", stra.c_str());
		}
	}
	config.SaveFile();
	m_bLoad = false;
	ParseConfigFile();
	return true;
}

std::vector<IO_MODULE>* CConfigFileManager::GetIOInputSetting()
{
	if (m_vIOInputSetting.empty())
	{
		return NULL;
	}
	return &m_vIOInputSetting;
}

std::vector<IO_MODULE>* CConfigFileManager::GetIOOutputSetting()
{
	if (m_vIOOutputSetting.empty())
	{
		return NULL;
	}
	return &m_vIOOutputSetting;
}

std::map<int, AXIS_SETTING>* CConfigFileManager::GetAxisSettingDict()
{
	if (m_dictAxisSetting.empty())
	{
		return nullptr;
	}
	return &m_dictAxisSetting;
}
